#include <head.h>
#include "./request_process.h"
void close_peer(int fd,int epfd);
void send_file(char *filename,int peerfd);
void send_response_head(int cfd,int no,const char *discription,const char *type,size_t len);
void send_dir(int fd,const char *path);
int get_line(int cfd, char *buf, int size)
{
    int i = 0;
    char c = '\0';
    int n;
    while ((i < size-1) && (c != '\n')) {  
        n = recv(cfd, &c, 1, 0);
        if (n > 0) {     
            if (c == '\r') {            
                n = recv(cfd, &c, 1, MSG_PEEK);
                if ((n > 0) && (c == '\n')) {              
                    recv(cfd, &c, 1, 0);
                } else {                       
                    c = '\n';
                }
            }
            buf[i] = c;
            i++;
        } else {      
            c = '\n';
        }
    }
    buf[i] = '\0';
    
    if (-1 == n)
    	i = n;

    return i;
}
void process_accept(int fd,int epfd)
{
    //1.读取数据
    //2.提取首部，
    //3.判断是否是GET方法
    //4.1是。判断请求的是文件夹还是目录。是目录，展示目录项，是文件，直接发送文件。
    //4.2不是。关闭连接，退出。
    int ret =0;
    struct stat sbuf;
    char *buf =calloc(1,1000);
    char method[20],protocl[20];
    char *fileName =calloc(100,1);
    char *path=NULL;    
    CLEAR_ARRAY(method);
    CLEAR_ARRAY(protocl);
    CLEAR_MEM(&sbuf,sizeof(sbuf));
    if(!buf || !fileName){
        goto end;
    }
    ret =get_line(fd,buf,1000); 
    printf("-----Request Head First Line-----------\n");
    printf("%s",buf);
    while(1){
        char tmp[1024];
        ret = get_line(fd,tmp,sizeof(tmp));
        if(tmp[0] == '\n' || ret == -1){
            break;
        }
    }
    if( buf[0] != '\n'){
        sscanf(buf,"%[^ ] %[^ ] %[^ ]" ,method,fileName,protocl);
        printf("method:%s fileName:%s protocol:%s\n",method,fileName,protocl);
        if(0==strncasecmp(method,"GET",3)){
            //char cwd_path[100];
            //CLEAR_ARRAY(cwd_path);
            //printf("current path:%s\n",getcwd(cwd_path,sizeof(cwd_path)));
            if(strlen(fileName)== 1 && fileName[0] =='/'){
                //显示根目录的内容
                path="./";
            }
            else{
                path =fileName+1;
            }
            ret = lstat(path,&sbuf);
            if(ret == -1){
                perror("lstat error");
                send404_page(fd);
                close_peer(fd,epfd);
            }
            else if(ret == 0){
                if(S_ISREG(sbuf.st_mode)){
                    //send_response_head(fd, 200, "OK", " Content-Type: text/plain; charset=iso-8859-1", sbuf.st_size);	
                    send_response_head(fd, 200, "OK", "image/png;", sbuf.st_size);	
                    send_file(path,fd);
                }
                else if(S_ISDIR(sbuf.st_mode)){
                    send_dir(fd,path);
                }
            }
        }
    }
    else{
        printf("invaild request head!\n");
        send404_page(fd);
    }
    /*
    while(1){
        CLEAR_MEM(buf,1000);
        ret = get_line(fd,buf,1000);
        if(ret<0){c
            break;
        }
    }
    */
end:
    if(fileName){
        free(fileName);
    }
    if(buf){
        free(buf);
    }
}
void send404_page(int fd)
{
    char *buf =calloc(1,1000);
    if(!buf){
        return;
    }
    snprintf(buf,1000,"HTTP/1.1 404 ERROR\r\n\r\n%s\r\n",ERROR_RESPONSE);
    write(fd,buf,strlen(buf));
    free(buf);
}
void send_file(char *filename,int peer)
{
    //open file
    // if success ,send fail
    //else return
    int ret=0;
    char buf[BUFSIZ];
    CLEAR_ARRAY(buf);
    int fd =open(filename,O_RDONLY);
    if(fd == -1){
        perror("open error");
        return ;
    }
    while(1){
        ret = read(fd,buf,BUFSIZ);
        if(ret == -1){
            if(errno == EAGAIN||errno == EINTR){
                continue;
            }
            else{
                return ;
            }
        }
        if(ret == 0){
            return;
        }
        if(ret>0){
            ret =  send(peer,buf,ret,0);
            if(ret == -1){
                if(errno == EAGAIN||errno == EINTR){
                    continue;
                }
                else{
                    return ;
                }
            }

            printf("send len =%d\n",ret);
        }
    }
}
void send_dir(int fd,const char *path)
{

}

void close_peer(int fd,int epfd)
{
    close(fd);
    epoll_ctl(epfd, EPOLL_CTL_DEL, fd,NULL);
}
void send_response_head(int cfd,int no,const char *discription,const char *type,size_t len)
{
	char buf[4096] = {0};
	
	sprintf(buf, "HTTP/1.1 %d %s\r\n", no, discription);
	sprintf(buf+strlen(buf), "Content-Type: %s\r\n", type);
	sprintf(buf+strlen(buf), "Content-Length:%d\r\n", len);
    sprintf(buf+strlen(buf), "\r\n");
	send(cfd, buf, strlen(buf), 0);
}